home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / SWAG9605.DDD / 0023_Mode-X one row pixel move.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-05-31  |  4.8 KB  |  139 lines

  1. {
  2. A couple of months ago, I posted an unfinished procedure to move a row of
  3. pixels one pixel to the left and asked for help. Didn't get any response
  4. (pretty normal, since it's really a lot of work to figure out someone else's
  5. assembler code :), but in the meantime I've been able to finish it. Don't know
  6. whether there's still anybody out there who can use it (the original
  7. requester, Fabian Thylman(n?), seems to have left Fidonet), but here it is
  8. anyway...
  9. }
  10.  
  11. PROCEDURE MoveRow1PixelLeft(x,y, length: WORD; VAR tempbuf);
  12. {For Mode-X, 320*200*4. Moves length pixels at (x,y) one position to the
  13. left.}{Tempbuf should be an array of byte/char, with size = length div 4.
  14. }{Public domain by Jonas Maebe (2:292/624.7). SWAG, you can include this if
  15. }{you guys feel like it :)
  16. }ASSEMBLER;
  17. VAR sisav, disav: word;
  18.     planecount: byte;
  19. ASM
  20.    cld
  21.    push ds
  22.    mov ax, $a000
  23.    mov di, x
  24.    mov ds, ax           {ds = videosegment}
  25.    mov bx, di           {bx = di = x}
  26.    mov ax, y
  27.    shr di, 2
  28.    shl ax, 5
  29.    add di, ax
  30.    shl ax, 2
  31.    add di, ax           {di = y * 160 + x div 4}
  32.    mov si, di           {source = destination = (x,y)}
  33.    and bl, 11b
  34.    mov bh, bl           {bh holds value for read plane}
  35.    dec bl               {write plane points to previous plane}
  36.    cmp bl, $ff          {bl = -1?}
  37.    jne @bl_ok
  38.    mov bl, 3            {set bl so it points to plane four (write plane)}
  39.    dec di               {and di to point to the previous memlocation}
  40.   @bl_ok:
  41.    mov cl, bl
  42.    mov bl, 1
  43.    shl bl, cl           {bl holds value to set the write plane}
  44.    mov cx, length       {cx holds the length of the row that has to be}
  45.                         {moved}
  46.    mov sisav, si
  47.    mov disav, di        {save si and di for later}
  48.    mov planecount, 3    {and initialize the plane counter}
  49.    mov dx, grac
  50.    mov ah, bl           {set read plane to value of writeplane, first save}
  51.    dec ah               {all pixels that'll be overwritten by the first move}
  52.    jns @ok
  53.    xor ah, ah           {the next few adjustments are still a mystery to me}
  54.   @ok:                  {and I've have found them out by trial and error.}
  55.    cmp ah, 3            {If anyone can explain *WHY* the read plane has to}
  56.    jne @ok2             {set this way, please do tell me...}
  57.    dec ah
  58.   @ok2:
  59.    mov al, 4
  60.    out dx, ax
  61.    mov si, di
  62.    sub cx, 3
  63.    inc si
  64.    les di, tempbuf
  65.    shr cx, 3
  66.    jnc @even
  67.    movsb
  68.   @even:                {all pixels that are to be overwritten are saved in}
  69.    rep movsw            {tempbuf}
  70.    mov si, sisav
  71.    mov di, disav
  72.    mov ax, $a000
  73.    mov cx, length
  74.    mov es, ax
  75.   @newplane:
  76.    mov dx, grac
  77.    mov ah, bh
  78.    mov al, 4
  79.    out dx, ax           {select read plane}
  80.   @writeplane:
  81.    mov dx, sequ
  82.    mov ah, bl
  83.    mov al, 2
  84.    out dx, ax           {select write plane}
  85.    shr cx, 3            {shr 2 because there are 4 planes + shr 1 because}
  86.    jnc @counter_even    {we're doing movsw's, only the last shifted-out}
  87.    movsb                {bit is kept in the carry flag}
  88.   @counter_even:
  89.    rep movsw            {move pixels}
  90.    cmp planecount, 0
  91.    je @end
  92.    mov cx, length       {reload the counter}
  93.    mov si, sisav        {restore si}
  94.    dec cx               {decrease the length by one; because we move on to}
  95.                         {the next pixel, the length of the row becomes one}
  96.                         {less}
  97.    mov di, disav        {restore di}
  98.    mov length, cx       {and save the length}
  99.    inc bh               {increase the read plane}
  100.    cmp bh, 4            {if it's four, wrap around since there are only 4}
  101.                         {planes to read from (and with 4 it would point to 5)}
  102.    jne @noreset_bh
  103.    mov bh, 0            {reset bh}
  104.    inc si               {next pixel because we reset bh}
  105.    mov sisav, si        {plane zero}
  106.   @noreset_bh:
  107.    cmp bl, 1000b        {test if it points to the 4th plane}
  108.    je @reset_bl
  109.    add bl, bl           {increase write plane (same as shl bl, 1)}
  110.    dec planecount
  111.    jnz @newplane        {planecounter 0 -> finish him! :)}
  112.    lds si, tempbuf
  113.    jmp @writeplane        {it doesn't -> don't reset}
  114.   @reset_bl:
  115.    mov bl, 1            {select plane 0}
  116.    inc di               {and point to the next pixel, same reason as with}
  117.    mov disav, di        {read plane}
  118.    dec planecount
  119.    jnz @newplane        {planecounter 0 -> finish him! :)}
  120.    lds si, tempbuf
  121.    jmp @writeplane
  122.   @end:
  123.    mov ah, 1
  124.    mov cl, bh
  125.    shl ah, cl
  126.    mov al, 2            {let the write plane point to the last pixel}
  127.    out dx, ax           {we've read (write plane = read plane)}
  128.    mov si, sisav
  129.    mov cx, length
  130.    shr cx, 2
  131.    jnc @even2
  132.    inc si
  133.   @even2:
  134.    add si, cx
  135.    xor bl, bl
  136.    mov es:[si], bl      {and zero the last pixel (erase it)}
  137.    pop ds               {restore data segment}
  138. END;
  139.